<!DOCTYPE html>
<html lang="zh-Hans">
<meta name="theme-color" content="#FFFFFF">


<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
  <meta name="theme-color" content="#202020"/>
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <link rel="shortcut icon" href="/images/favicon.ico" type="image/x-icon" />
  <link rel="icon" sizes="any" mask href="/images/favicon.ico" /> 
  
  

  <!-- viewjs support -->
  
    <!-- for theme: default is false -->
    <!-- for page: default is true -->
    <link  href="./css/viewer.min.css" rel="stylesheet" >
    <script src="./js/viewer.min.js" type="text/javascript" charset="utf-8"></script>
  
  
  
    <meta name="keywords" content="" />
  

  
    <meta name="description" content="分享 Java 技术，做有趣的程序员" />
  
  
  <link rel="icon" type="image/x-icon" href="/logo.png">
  <title>我的简历 [ H E R O ]</title>
  
    <!-- stylesheets list from config.yml -->
    
      <link rel="stylesheet" href="//cdn.bootcss.com/pure/1.0.0/pure-min.css">
    
      <link rel="stylesheet" href="/css/xoxo.css">
    
  
<meta name="generator" content="Hexo 5.4.0"></head>


<body>
  <div class="nav-container">
    <nav id="menu" class="home-menu pure-menu pure-menu-horizontal">
  <a class="pure-menu-heading" href="/">
    <!-- <img class="avatar" src="/images/logo.png"> -->
    <span class="title">H E R O</span>
  </a>

  <ul class="pure-menu-list clearfix">
      
          
            <li class="pure-menu-item"><a href="/" class="pure-menu-link">首页</a></li>
          
      
          
            <li class="pure-menu-item"><a href="/archives/" class="pure-menu-link">归档</a></li>
          
      
          
            <li class="pure-menu-item"><a href="/tags/" class="pure-menu-link">标签</a></li>
          
      
          
            <li class="pure-menu-item"><a href="/about/" class="pure-menu-link">关于</a></li>
          
      
          
            <li class="pure-menu-item"><a href="/atom.xml" class="pure-menu-link">订阅</a></li>
          
      
  </ul>
   
</nav>
  </div>

  <div class="container" id="content-outer">
    <div class="inner" id="content-inner">
      <article class="post page" id="page">
  <header class="post-header text-center">
  </header>
  <div class="post-content">
    
        <h2 id="张博的简历"><a href="#张博的简历" class="headerlink" title="张博的简历"></a>张博的简历</h2><p><img src="https://imgchr.com/i/EqsYGD" alt="233"></p>
<h1 id="联系方式"><a href="#联系方式" class="headerlink" title="联系方式"></a>联系方式</h1><ul>
<li>手机：18413246170 （微信同号）</li>
<li>Email：haozhangbo123@gmail.com</li>
</ul>
<h1 id="个人信息"><a href="#个人信息" class="headerlink" title="个人信息"></a>个人信息</h1><ul>
<li><strong>张博</strong>/男/1993</li>
<li>本科/杭州电子科技大学  计算机科学与技术专业</li>
<li>工作年限：2年</li>
<li>技术博客：<a href="https://jacobchang.cn">https://jacobchang.cn</a></li>
<li>英语水平：六级（无障碍阅读各类英文技术文章和博客）</li>
<li>期望职位：后端开发（主要语言Java，不排斥学习其他语言）</li>
</ul>
<h1 id="工作经历"><a href="#工作经历" class="headerlink" title="工作经历"></a>工作经历</h1><h2 id="美团点评-（-2017年6月-至今-）"><a href="#美团点评-（-2017年6月-至今-）" class="headerlink" title="美团点评 （ 2017年6月 ~ 至今 ）"></a>美团点评 （ 2017年6月 ~ 至今 ）</h2><h3 id="到店餐饮促销基础服务"><a href="#到店餐饮促销基础服务" class="headerlink" title="到店餐饮促销基础服务"></a>到店餐饮促销基础服务</h3><p>主要负责 C 端的获取促销详情和 B 的促销活动的创建。在我负责期间，将缓存加载速度提高了近千倍。遇到了集群本地缓存不一致的情况，通过深刻分析缓存加载流程，定位原因，解决了缓存加载过程的 BUG，不但解决了缓存不一致的问题，还有效提高了服务刚刚启动后的超时问题。同时将单机QPS提高到1w+。还有内存泄露问题，服务发布一段时间一会 JVM 老年代占用巨高不下，Full GC 之后也并没有明显改善，通过对 JVM 的内存快照进行分析，结合代码逻辑，最终定位到是堆外内存泄露，由于在压缩字符串后没有关闭流，提高了服务的稳定性。</p>
<h3 id="促销活动生命周期的状态流转维护服务"><a href="#促销活动生命周期的状态流转维护服务" class="headerlink" title="促销活动生命周期的状态流转维护服务"></a>促销活动生命周期的状态流转维护服务</h3><p>保证促销活动在规定的时间开始和结束。主要的技术难点在于凌晨 0 点会有大量的活动同时开始，这样如果单个写入数据库，会对数据库造成很大的压力，并且也会活动开始时间比规定时间有很大的延迟（大约 5 mins），通过优化架构和逻辑，引入阻塞队列配合消息中间件，达到批量获取和单个获取的一种平衡，有效的减少的数据库的压力，同时活动开始或结束的延迟也下降到了秒级别（5s 一下）。同时对于秒杀活动采取提前修改数据库，C 端把控开始时间的方式保证秒杀活动不会延迟开始。</p>
<h3 id="其他项目"><a href="#其他项目" class="headerlink" title="其他项目"></a>其他项目</h3><ul>
<li>促销数据平台建设<ul>
<li>负责拼团活动的创建、修改、获取、虚库存查询接口开发；活动状态变更消息队列开发，充分借鉴团购活动的模型，为拼团活动各个接口开发，充分考虑了拼团活动对于该队列的需求和该队列的通用性，将该队列定位为所有类型活动都可以使用的队列，目前项目已经成功上线，获得了不俗的效果。</li>
</ul>
</li>
<li>美团到餐拼团<ul>
<li>负责将日志等数据导入到 ElasticSearch 集群，系统学习了 ElasticSearch 官方文档，通过 Kafka 和 Storm 等工具分析日志后导入集群，然后通过不同的查询语句来获取一些简单的数据，同比环比增长等。</li>
</ul>
</li>
</ul>
<h1 id="技术文章"><a href="#技术文章" class="headerlink" title="技术文章"></a>技术文章</h1><ul>
<li><a href="https://jacobchang.cn/preparation-and-init-of-classloader.html">03-25 / Java类加载器的准备和初始化</a></li>
<li><a href="https://jacobchang.cn/lock-of-mysql.html">09-20 / MySQL 中的锁</a></li>
</ul>
<p>更多技术文章在个人博客：<a href="https://jacobchang.cn/">黄小豆的博客</a></p>
<h1 id="自我评价"><a href="#自我评价" class="headerlink" title="自我评价"></a>自我评价</h1><p>​        从事 Java 开发接近 2 年，对 JVM 有一定的了解，熟练使用 Java 并发编程，对于常见的消息队列、缓存、数据库等中间件能够熟练使用并且熟悉原理。熟悉常见数据结构和算法，有较好的计算机网络基础。熟悉分布式系统的设计和应用。有良好的工程能力和经验，又很强的学习能力，并且有学习欲望。积极主动，乐于分享。</p>
<hr>
<h1 id="致谢"><a href="#致谢" class="headerlink" title="致谢"></a>致谢</h1><p>感谢您花时间阅读我的简历，期待能有机会和您共事。</p>

      
  </div>
</article>
    </div>

    

  </div>
  <footer class="footer text-center">
    <div id="bottom-inner">
        <a class="bottom-item-hide" href="https://jacobchang.cn/" target="_blank">主站</a>
        <!-- <a class="bottom-item-hide">·</a> -->
        <!-- <a class="bottom-item-hide" href="" target="_blank">备份站点</a> -->
        <a class="bottom-item-hide">·</a>
        <a class="bottom-item-hide" href="https://github.com/coderbean" target="_blank">GitHub</a>
        <a class="bottom-item-hide">·</a>
        <a class="bottom-item" href="https://hexo.io" target="_blank">Powered by hexo</a>
        <a class="bottom-item">·</a>
        <a class="bottom-item" href="https://github.com/coderbean/hexo-theme-xoxo" target="_blank">Theme xoxo</a>
    </div>
    <div id="bottom-inner">
        <a class="bottom-item-hide" target="_blank" rel="noopener" href="https://beian.miit.gov.cn">备案号：浙ICP备2021033778号-1</a> 
        <a class="bottom-item-hide">·</a>
        <a id="copyright" class="bottom-item"></a>
    </div>
</footer>

<script language="javascript" type="text/javascript">
    var df = new Date();
    var year = df.getFullYear();
    document.getElementById("copyright").innerHTML = "Copyright © 2017 – " + year + " 黄小豆";
</script>
  

<script>
  (function(window, document, undefined) {

    var timer = null;

    function returnTop() {
      cancelAnimationFrame(timer);
      timer = requestAnimationFrame(function fn() {
        var oTop = document.body.scrollTop || document.documentElement.scrollTop;
        if (oTop > 0) {
          document.body.scrollTop = document.documentElement.scrollTop = oTop - 50;
          timer = requestAnimationFrame(fn);
        } else {
          cancelAnimationFrame(timer);
        }
      });
    }

    var hearts = [];
    window.requestAnimationFrame = (function() {
      return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function(callback) {
          setTimeout(callback, 1000 / 60);
        }
    })();
    init();

    function init() {
      css(".heart{z-index:9999;width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: absolute;}.heart:after{top: -5px;}.heart:before{left: -5px;}");
      attachEvent();
      gameloop();
      addMenuEvent();
    }

    function gameloop() {
      for (var i = 0; i < hearts.length; i++) {
        if (hearts[i].alpha <= 0) {
          document.body.removeChild(hearts[i].el);
          hearts.splice(i, 1);
          continue;
        }
        hearts[i].y--;
        hearts[i].scale += 0.004;
        hearts[i].alpha -= 0.013;
        hearts[i].el.style.cssText = "left:" + hearts[i].x + "px;top:" + hearts[i].y + "px;opacity:" + hearts[i].alpha + ";transform:scale(" + hearts[i].scale + "," + hearts[i].scale + ") rotate(45deg);background:" + hearts[i].color;
      }
      requestAnimationFrame(gameloop);
    }

    /**
     * 设置点击事件
     * 
     * - 回到顶部
     * - 出现爱心
     */
    function attachEvent() {
      var old = typeof window.onclick === "function" && window.onclick;
      var logo = document.getElementById("menu");
      if (logo) {
        logo.onclick = function(event) {
          // returnTop();
          old && old();
          createHeart(event);
        }
      }
      
    }

    function createHeart(event) {
      var d = document.createElement("div");
      d.className = "heart";
      hearts.push({
        el: d,
        x: event.clientX - 5,
        y: event.clientY - 5,
        scale: 1,
        alpha: 1,
        color: randomColor()
      });
      document.body.appendChild(d);
    }

    function css(css) {
      var style = document.createElement("style");
      style.type = "text/css";
      try {
        style.appendChild(document.createTextNode(css));
      } catch (ex) {
        style.styleSheet.cssText = css;
      }
      document.getElementsByTagName('head')[0].appendChild(style);
    }

    function randomColor() {
      // return "rgb(" + (~~(Math.random() * 255)) + "," + (~~(Math.random() * 255)) + "," + (~~(Math.random() * 255)) + ")";
      return "#F44336";
    }

    function addMenuEvent() {
      var menu = document.getElementById('menu-main-post');
      if (menu) {
        var toc = document.getElementById('toc');
        if (toc) {
          menu.onclick = function() {
            if (toc) {
              if (toc.style.display == 'block') {
                toc.style.display = 'none';
              } else {
                toc.style.display = 'block';
              }
            }
          };
        } else {
          menu.style.display = 'none';
        }
      }
    }

  })(window, document);
</script>

  


  <script>
      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
                  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
              m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
      })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
      ga('create', 'UA-155080039-1', 'auto');
      ga('send', 'pageview');
  </script>


  
<link rel='stylesheet' href='https://s3-us-west-2.amazonaws.com/s.cdpn.io/1462889/unicons.css'>

<div class="progress-wrap">
    <svg class="progress-circle svg-content" width="100%" height="100%" viewBox="-1 -1 102 102">
        <path d="M50,1 a49,49 0 0,1 0,98 a49,49 0 0,1 0,-98" />
    </svg>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js'></script>
<script>

    (function ($) {
        "use strict";
        $(document).ready(function () {
            "use strict";

            //Scroll back to top

            var progressPath = document.querySelector('.progress-wrap path');
            var pathLength = progressPath.getTotalLength();
            progressPath.style.transition = progressPath.style.WebkitTransition = 'none';
            progressPath.style.strokeDasharray = pathLength + ' ' + pathLength;
            progressPath.style.strokeDashoffset = pathLength;
            progressPath.getBoundingClientRect();
            progressPath.style.transition = progressPath.style.WebkitTransition = 'stroke-dashoffset 10ms linear';
            var updateProgress = function () {
                var scroll = $(window).scrollTop();
                var height = $(document).height() - $(window).height();
                var progress = pathLength - (scroll * pathLength / height);
                progressPath.style.strokeDashoffset = progress;
            }
            updateProgress();
            $(window).scroll(updateProgress);
            var offset = 50;
            var duration = 550;
            jQuery(window).on('scroll', function () {
                if (jQuery(this).scrollTop() > offset) {
                    jQuery('.progress-wrap').addClass('active-progress');
                } else {
                    jQuery('.progress-wrap').removeClass('active-progress');
                }
            });
            jQuery('.progress-wrap').on('click', function (event) {
                event.preventDefault();
                jQuery('html, body').animate({ scrollTop: 0 }, duration);
                return false;
            })


        });

    })(jQuery);
</script>

  
<!-- for theme: default is false -->
<!-- for page: default is true -->
<!-- 图片查看器实例配置 -->
<script type="text/javascript">
    //默认设置， 可以根据个人需求和喜好进行配置
    //详细参考官方说明
    Viewer.setDefaults({
        //设置初始缩放 default: 1
        zoomRatio: [0.5],
        // 过渡动画
        transition:true,
        // 显示工具条
        toolbar: false,
    });
    //获得content中所有的图片， 不同主题可能有所不同
    //为了和其他的图片区别开来 所以在markdown中插入图片的时候使用独特的记号
    //为了一次性得到所有的图片我这里采用的是class = 'article-image'
    var article = document.querySelector('.post-content');
    if(article!=null) {
        var imageList = article.getElementsByTagName('img');
        //将获取到的HTMLCollections转化成Array
        var imageArray = new Array();
        Array.prototype.forEach.call(imageList, element => {
            imageArray.push(element);
        });
        //设置每个图片成为图片组
        Array.prototype.forEach.call(imageList, element => {
            var viewer1 = new Viewer(element);
            viewer1.images = imageArray;
            viewer1.length = imageArray.length;
        });
    }

    
</script>

  
  <! -- mathjax config similar to math.stackexchange -->

<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
          inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
                processEscapes: true
                    
}
  
        });
</script>

<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
            skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
                  
}
    
        });
</script>

<script type="text/x-mathjax-config">
MathJax.Hub.Queue(function() {
            var all = MathJax.Hub.getAllJax(), i;
            for(i=0; i < all.length; i += 1) {
                            all[i].SourceElement().parentNode.className += ' has-jax';
                                    
            }
                
        });
</script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML"></script>

</script>

  
</body>

</html>